/*
 * Copyright 2006 Mark Bakker <mark.bakker AT gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package org.gwtsvg.client.path;

import org.gwtsvg.client.BasicShape;
import org.gwtsvg.client.Coordinate;
import org.gwtsvg.client.SVGPanel;
import org.gwtsvg.client.basicshapes.Eclipse;
import org.gwtsvg.client.dom.ExtDOM;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * SVG Path.
 */
public class Path extends BasicShape {

  private List coordinate = new ArrayList();

  public Path() {
    super(ExtDOM.createElementNS(SVGPanel.DEFAULT_NAMESPACE, "path"));
  }

  public void addClosePath(Coordinate coordinate) {
    this.coordinate.add(new PathClose(coordinate));
    setPath(this.coordinate);
  }

  public void addControlPoint(Coordinate coordinate) {
    this.coordinate.add(new PathControlPoint(coordinate));
    setPath(this.coordinate);
  }

  public void addCubicBezier(Coordinate start, Coordinate controlpoint1,
      Coordinate controlpoint2, Coordinate end) {
    this.coordinate.add(new PathCubicBezierStart(start));
    this.coordinate.add(new PathControlPoint(controlpoint1));
    this.coordinate.add(new PathControlPoint(controlpoint2));
    this.coordinate.add(new PathCubicBezierEnd(end));
    setPath(this.coordinate);
  }

  public void addEllipticalCurve(Eclipse curve, double rotation, boolean sweep,
      boolean largeArc, Coordinate end) {
    this.coordinate.add(new PathEllipticalCurve(curve, rotation, sweep,
        largeArc, end));
    setPath(this.coordinate);
  }

  public void addLineTo(Coordinate coordinate) {
    this.coordinate.add(new PathLine(coordinate));
    setPath(this.coordinate);
  }

  public void addMoveTo(Coordinate coordinate) {
    this.coordinate.add(new PathMove(coordinate));
    setPath(this.coordinate);
  }

  public void addQuadraticBezier(Coordinate start, Coordinate controlpoint,
      Coordinate end) {
    this.coordinate.add(new PathQuadraticBezierStart(start));
    this.coordinate.add(new PathControlPoint(controlpoint));
    this.coordinate.add(new PathQuadraticBezierEnd(end));
    setPath(this.coordinate);
  }

  private void setPath(List path) {
    this.coordinate = path;

    String pathString = "";

    for (Iterator iter = path.iterator(); iter.hasNext();) {
      Coordinate coord = (Coordinate) iter.next();
      if (coord instanceof PathLine) {
        pathString = pathString + ((PathLine) coord).getCoordinate() + " ";
      } else if (coord instanceof PathMove) {
        pathString = pathString + ((PathMove) coord).getCoordinate() + " ";
      } else if (coord instanceof PathCubicBezierStart) {
        pathString = pathString
            + ((PathCubicBezierStart) coord).getCoordinate() + " ";
      } else if (coord instanceof PathCubicBezierEnd) {
        pathString = pathString
            + ((PathCubicBezierEnd) coord).getCoordinate() + " ";
      } else if (coord instanceof PathQuadraticBezierStart) {
        pathString = pathString
            + ((PathQuadraticBezierStart) coord).getCoordinate() + " ";
      } else if (coord instanceof PathQuadraticBezierEnd) {
        pathString = pathString
            + ((PathQuadraticBezierEnd) coord).getCoordinate() + " ";
      } else if (coord instanceof PathControlPoint) {
        pathString = pathString
            + ((PathControlPoint) coord).getCoordinate() + " ";
      } else if (coord instanceof PathClose) {
        pathString = pathString + ((PathClose) coord).getCoordinate()
            + " ";
      } else if (coord instanceof PathEllipticalCurve) {
        pathString = pathString
            + ((PathEllipticalCurve) coord).getCoordinate() + " ";
      }
    }
    setAttributeNS(getElement(), "d", pathString);
  }

}
